package com.todo.biz.infrastructure.repository.impl;

import com.todo.biz.common.enums.CommentTypeEnum;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.MathUtils;
import com.todo.biz.infrastructure.entity.condition.CommentCondition;
import com.todo.biz.infrastructure.entity.po.CommentPO;
import com.todo.biz.infrastructure.mapper.CommentMapper;
import com.todo.biz.infrastructure.repository.CommentRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * (Comment)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 21:10:03
 */
@Repository("commentRepository")
public class CommentRepositoryImpl implements CommentRepository {

    @Resource
    private CommentMapper commentMapper;


    @Override
    public PageResult<CommentPO> queryCommentByCondition(CommentCondition commentCondition) {
        PageResult<CommentPO> pageResult = new PageResult<>();
        if (commentCondition == null) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        pageResult.setPageNum(commentCondition.getPageIndex());
        pageResult.setPageSize(commentCondition.getPageSize());
        long count = queryCountByCondition(commentCondition);
        if (count <= 0) {
            return pageResult;
        }
        pageResult.setPageCount((int) MathUtils.divide(count, commentCondition.getPageSize()));
        pageResult.setTotal(count);
        List<CommentPO> commentPOList = commentMapper.queryCommentListByCondition(commentCondition);
        if (CollectionUtils.isEmpty(commentPOList)) {
            pageResult.setHasNext(false);
            return pageResult;
        }
        pageResult.setResults(commentPOList);
        pageResult.setCurrentIndex(commentPOList.get(0).getId());
        pageResult.setHasNext(commentPOList.size() >= commentCondition.getPageSize());
        return pageResult;
    }

    @Override
    public Long queryCountByCondition(CommentCondition commentCondition) {
        if (commentCondition == null || commentCondition.getPageSize() <= 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        return commentMapper.queryCountByCondition(commentCondition);
    }

    @Override
    public CommentPO queryCommentPOById(Long id) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        return commentMapper.queryCommentPOById(id);
    }

    @Override
    public List<CommentPO> queryCommentListByParentId(Long parentId, Integer pageSize, Integer pageIndex) {
        if (parentId == null || parentId < 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }

        return commentMapper.queryCommentListByParentId(parentId, pageSize, pageIndex);
    }

    @Override
    @Transactional
    public Boolean insertCommentPO(CommentPO commentPO) {
        if (commentPO == null) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        //子评论数增加
        //评论评论
        if (commentPO.getCommentType() == CommentTypeEnum.COMMENT.getType()) {
            Long parentId = commentPO.getParentId();
            parentCommentPlus(parentId);
        } else if (commentPO.getCommentType() == CommentTypeEnum.CONTENT.getType()) {
            //内容评论内容，需要计算当前层级
            commentPO.setCommentStorey(queryCommentCurrentStorey(commentPO.getParentId()) + 1);
        }
        return commentMapper.insertCommentPO(commentPO) > 0;
    }

    /**
     * 根据父id查询评论总数
     *
     * @param parentId
     * @return
     */
    private Integer queryCommentCurrentStorey(Long parentId) {
        Integer storey = commentMapper.queryCommentCurrentStorey(parentId);
        return storey == null ? 0 : storey;
    }

    /**
     * 父评论数量增加
     *
     * @param parentId
     */
    private void parentCommentPlus(Long parentId) {
        CommentPO parentCommentPO = queryCommentPOById(parentId);
        if (parentCommentPO != null) {
            int count = parentCommentPO.getChildCount() + 1;
            commentMapper.updateCommentCountById(count, parentCommentPO.getId());
        }
    }

    @Override
    @Transactional
    public Boolean removeCommentPOById(Long id) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        CommentPO commentPO = queryCommentPOById(id);
        if (commentPO == null) {
            return true;
        }
        //子评论内容则减少父评论数量
        if (commentPO.getCommentType() == 2) {
            CommentPO parentCommentPO = queryCommentPOById(commentPO.getParentId());
            int count = parentCommentPO.getChildCount() - 1;
            commentMapper.updateCommentCountById(count, parentCommentPO.getId());
        }
        commentMapper.removeCommentByParentId(id);
        commentMapper.removeCommentPOById(id);
        return true;
    }

}
